//-----------------------------------------------------------------------
// <copyright file="COMClient.cs" company="DylanBox">
// Copyright (c) DylanBox Corporation. All rights reserved.
// </copyright>
// <summary>Calling .NET components from COM Client</summary>
// <reference>
//	Exposing .NET Framework Components to COM
//		http://msdn.microsoft.com/en-us/library/aa720072(v=vs.71).aspx
//  COM Interop Part 2: C# Server Tutorial
//		http://msdn.microsoft.com/en-us/library/aa645738(v=vs.71).aspx
//	.NET - COM Interoperability
//		http://www.codeproject.com/KB/COM/COM_DOTNET_INTEROP.aspx

// Notes:
//		1. .Net assembly must has marked as COMVisible
//		2. use the Guid attribute on interfaces and classes to expose them as COM objects 
//		3. use RegAsm to register a .NET Framework program in Registry for use by COM clients 
//			and create a type library (.tlb file) from a .NET Framework program, 
//			This tlb file will be used like c++ head file
//		4. You MUST copy .NET assembly into the COMClient folder. 
//			COMClient will interop with it!
// </reference>
// <author>Dylan</author>
//-----------------------------------------------------------------------

#include <windows.h>
#include <stdio.h>

#pragma warning (disable: 4278)
#define USINGPROJECTSYSTEM 1
// To use managed-code servers like the C# server, 
// we have to import the common language runtime:
#import <mscorlib.tlb> raw_interfaces_only


// For simplicity, we ignore the server namespace and use named guids:
#if defined (USINGPROJECTSYSTEM)
#import "..\RegisterCSharpLibAndExportTLB\CSharpLib.tlb" no_namespace named_guids
#else  // Compiling from the command line, all files in the same directory
#import "CSharpLib.tlb" no_namespace named_guids
#endif

int main(int argc, char* argv[])
{
    IManagedLib *cpi = NULL;
	int retval = 1;

	// Initialize COM and create an instance of the InterfaceImplementation class:
	CoInitialize(NULL);
	HRESULT hr = CoCreateInstance(CLSID_ManagedLib,
               NULL,
               CLSCTX_INPROC_SERVER,
               IID_IManagedLib,
               reinterpret_cast<void**>(&cpi));

	if (FAILED(hr))
	{
		printf("Couldn't create the instance!... 0x%x\n", hr);
	}
	else
	{
		 if (argc > 1)
		 {
			printf("Calling function.\n");
		 // The variable cpi now holds an interface pointer    // to the interface IManagedLib.
		 // If you are on an OS that uses ASCII characters at the command prompt, notice that the ASCII characters are 
		 // automatically marshaled to Unicode for the C# code.

		 if (cpi->PrintHi(argv[1]) == 33)
			retval = 0;

		 printf("Returned from function.\n");
	  }
	  else
		 printf ("Usage:  COMClient <name>\n");
      
	  cpi->Release();
	  cpi = NULL;
   }
  
   // Be a good citizen and clean up COM:
   CoUninitialize();
   return retval;
}